#include "denis.h"
#include "denis_leng_pack.h"

QStringList Denis::db_keys;
QString Denis::Dir[2];
//QStringList Denis::FileList;

Denis::Denis(QObject *parent) :
    QObject(parent)
{
}

const QString* Denis::getDataBaseUserName()
{
    return &db_keys[0];
}

/*
  Процедура дає користувачу змогу вибрати нове дерево каталогів
*/
void Denis::SelectDir(QWidget *This, QTreeView *Out, QTextEdit *Log, int InOrOut)
{
    //Запитуємо користувача
    Dir[InOrOut] = QFileDialog::getExistingDirectory(
                This,
                tr("Select Directory"),
                "/",
                QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
                );
    //Оброблюємо відповідь
    QFileSystemModel *model = new QFileSystemModel;
    model->setRootPath("/home/");

    //Вивиодимо результат
    Out->setModel(model);
    Out->setRootIndex(model->index(Dir[InOrOut]));

    Log->append(land_SelectDir_report0 + Dir[InOrOut] + "\"");
    //delete model;
}

const QString* Denis::getRootDirPath(int InOrOut)
{
    return &Dir[InOrOut];
}

/*
  Дана процедура дозволяє встановити, пароль/логин на доступ до бази даних
*/
bool Denis::keyring()
{
    QFile f;
    f.setFileName(db_config_filename);

    // Перевіряємо чи є дані авторизації для бази даних
    if( !f.exists() || (f.size() == 0) )
    {
        QString file;
        bool stop = false;
        do{
            file = Denis::keyring_dialog();
            if((file.length() != 0))
                switch(QMessageBox::question(NULL,lang_ask_title,file + '.' + lang_ask_text, lang_ask_ok, lang_ask_no, QString::null, 0, 1))
                {
                case 1:
                    return false;
                    break;
                default:;
                }
            else
                break;

        }while( (file.length() != 0) && !stop);

        f.open(QIODevice::WriteOnly | QIODevice::Text);

        QByteArray tmp;
        tmp.append(db_keys.at(0));
        f.write(tmp);
        f.write("\n");
        tmp.clear();
        tmp.append(db_keys.at(1));
        f.write(tmp);
        f.close();
    }
    return true;
}
/*
  Дана процедура дозволяє завантажити с файла, пароль/логин на доступ до бази даних
*/
void Denis::keyring_load()
{
    QFile f;
    f.setFileName(db_config_filename);
    f.open(QIODevice::ReadOnly | QIODevice::Text);
    db_keys.clear();
    db_keys.append(f.readLine().split(10)[0]);
    db_keys.append(f.readLine());
    f.close();
}

/*
  Дана процедура дозволяє вилучити, пароль/логин на доступ до бази даних
*/
void Denis::keyring_erase()
{
    QFile f;
    f.setFileName(db_config_filename);
    if( f.exists() )
    {
        f.remove();
    }
    else
    {
        return;
    }
}
/*
  Дана процедура дозволяє запитати у користувача, пароль/логин на доступ до бази даних
*/
QString Denis::keyring_dialog()
{
    QDialog dialog;
    dialog.setWindowTitle(lang_keyring_dialog_dialog_title);

    QPushButton
            *yes = new QPushButton(lang_keyring_dialog_yes, &dialog);

    connect(yes, SIGNAL(clicked()), &dialog, SLOT(close()));

    QLabel
            *Login_text = new QLabel(lang_keyring_dialog_Login_text, &dialog),
            *Password_text = new QLabel(lang_keyring_dialog_Password_text, &dialog),
            *Password_text_confirm = new QLabel(lang_keyring_dialog_Password_text_confirm, &dialog);

    QLineEdit
            *Login = new QLineEdit(&dialog),
            *Password = new QLineEdit(&dialog),
            *Password_confirm = new QLineEdit(&dialog);


    Password->setEchoMode(QLineEdit::Password);
    Password_confirm->setEchoMode(QLineEdit::Password);

    QVBoxLayout *lay = new QVBoxLayout(&dialog);
    lay->addWidget(Login_text);
    lay->addWidget(Login);

    lay->addWidget(Password_text);
    lay->addWidget(Password);
    lay->addWidget(Password_text_confirm);
    lay->addWidget(Password_confirm);

    lay->addWidget(yes);

    dialog.exec();

    if(
            (Login->text().length() == 0) ||
            (Password->text().length() == 0) ||
            (Password_confirm->text().length() == 0) ||
            (Password->text().length() != Password_confirm->text().length())
            )
    {
        return lang_keyring_dialog_rezalt_1;
    }
    else
    {
        if((Password->text() != Password_confirm->text()))
        {
            return lang_keyring_dialog_rezalt_2;
        }
    }
    db_keys.clear();
    db_keys.append(Login->text());
    db_keys.append(Password->text());
    return "";
}

/*
  Процедура дозволяє запитати у користувача IP
*/
QString Denis::ip_dialog()
{
    QDialog dialog;
    dialog.setWindowTitle(lang_keyring_dialog_dialog_title);

    QPushButton
            *yes = new QPushButton(lang_ip_dialog_yes, &dialog);

    connect(yes, SIGNAL(clicked()), &dialog, SLOT(close()));

    QLabel
            *IP_text = new QLabel(lang_ip_dialog_Login_text, &dialog);

    QLineEdit
            *IP = new QLineEdit(&dialog);

    QVBoxLayout *lay = new QVBoxLayout(&dialog);
    lay->addWidget(IP_text);
    lay->addWidget(IP);

    lay->addWidget(yes);

    IP->setText("127.0.0.1");
    dialog.exec();
    return IP->text();
}

/*
  Процедура перевіряє IP на коректність
*/
bool Denis::ip_check(QString IP)
{
    int dot_counter = 0;
    QString normal_symbol = "1234567890.";

    for(int i = 0; i < IP.length(); i++)
    {
        if(normal_symbol.indexOf(IP[i]) == -1)
            return false;
        if(IP[i] == '.')
            dot_counter++;
    }

    if(dot_counter != 3)
        return false;

    QStringList segments = IP.split('.');

    if(
            (segments.at(0).length() > 3) ||
            (segments.at(1).length() > 3) ||
            (segments.at(2).length() > 3) ||
            (segments.at(3).length() > 3) ||

            (segments.at(0).length() < 1) ||
            (segments.at(1).length() < 1) ||
            (segments.at(2).length() < 1) ||
            (segments.at(3).length() < 1)
            )
            return false;

    return true;
}
/*
get list of files in root dir and all subdir
 */
void Denis::buildFileList(QStringList &FileList, int InOrOut)
{
    if (Dir[InOrOut].length() == 0)
    {
        return;
    }

    FileList.clear();
    int len = Dir[InOrOut].length();

    FileListBulder(Dir[InOrOut],FileList,len);
}
/*
 Recurse directories
 */
void Denis::FileListBulder(QString dir, QStringList &out, int len)
{
    //Search Files and Dirs
    QDir FS(dir);
    QFileInfoList Files = FS.entryInfoList(QStringList()<< "*",QDir::Files);
    QFileInfoList Dirs = FS.entryInfoList(QStringList()<< "*",QDir::Dirs | QDir::NoDotAndDotDot);

    //Saving relative path to the files
    for (int i = 0; i < Files.count(); i++)
    {
        out.append(Files.at(i).filePath().remove(0,len));
        out.append(QString::number(Files.at(i).size()));
    }

    //Searching in subdirs
    for (int i = 0; i < Dirs.count(); i++)
        FileListBulder(Dirs.at(i).filePath(),out,len);
}

/*
Output file names
*/
void Denis::printFileList(QStringList &FileList,QTextEdit *Log)
{
    for (int i = 0; i < FileList.length(); i++)
        Log->append(FileList.at(i));
}
/*
 Get pointer to list of files
*/
/*
const QStringList* Denis::getFileList()
{
    return &FileList;
}
*/
/*
Функція повертає реакцію користувача на зміни в ФС.

Повертає:
   1 - згода,
   0 - ні,
   -1 - помилка переданих параметрів
Приймає:
   QStringList &FileList - список файлів
   int out - індекс першого файлу що буде відправлено
   int del - індекс першого файлу що буде видалено

   якщо якогось з двох вище заданих індексів не має - встановити в "-1" (можна і обидва)

   значення out = 0 вказує що немає файлів для завантаження (тому що параметер in завжди = 0 і не передаєтся, але перекриваєтся через out чи del...)
*/
int Denis::showFileSystemWarnings(QStringList &FileList, int out, int del)
{
    if (
            (FileList.length() == 0) ||
            (FileList.length() <= out) ||
            (FileList.length() <= del) ||
            ((out == del) && (out != -1)) ||
            (out > del) ||
            (out < -1) ||
            (del < -1)
            )
        return -1;

    QDialog dialog;
    dialog.setWindowTitle(lang_warnings_name);

    QPushButton *yes = new QPushButton(lang_warnings_dialog_button_yes, &dialog);

    connect(yes, SIGNAL(clicked()), &dialog, SLOT(close()));

    QTextEdit
            *Report = new QTextEdit(&dialog);

    if (del != -1)
    {
        Report->append(lang_warnings_dialog_del);
        for(int i = del; i < FileList.length(); i++)
            Report->append("   "+FileList[i]);
    }

    if ((out != 0) && (del != 0))
    {
        int n = 0;
        if ((out == -1) && (del == -1))
            n = FileList.length();
        else
            if ((out == -1) && (del =! -1))
                n = del;
            else
                n = out;

        Report->append(lang_warnings_dialog_in);
        for(int i = 0; i < n; i++)
            Report->append("   "+FileList[i]);
    }

    if (out != -1)
    {
        Report->append(lang_warnings_dialog_out);
        if (del == -1) del = FileList.length();
        for(int i = out; i < del; i++)
            Report->append("   "+FileList[i]);
    }

    QCheckBox
            *Order = new QCheckBox(&dialog);
    Order->setVisible(true);
    Order->setText(lang_warnings_dialog_text_warn);
    Order->setChecked(false);

    QVBoxLayout *lay = new QVBoxLayout(&dialog);
    lay->addWidget(Report);
    lay->addWidget(Order);
    lay->addWidget(yes);

    dialog.setGeometry(100,100,640,480);
    dialog.exec();
    if (Order->isChecked())
        return 1;
    return 0;
}

void Denis::FileCopy(QString in, QString out)
{
    QFile
            F1(in),
            F2(out);

    QDir dir;
    QString path = out;


    int index = path.length() - 1;

    if(index > 1)
        for(index; index >= 0; index--)
        {
            if(path.at(index) == '/')
                break;
        }
    path.truncate(index + 1);
    dir.setPath(path);
    if (!dir.exists())
        dir.mkdir(path);

    F1.open(QFile::ReadOnly);
    F2.open(QFile::WriteOnly);

    F2.write(F1.readAll());
    F1.close();
    F2.close();
}

void Denis::FileMove(QString in, QString out)
{
    QFile
            F1(in),
            F2(out);

    F1.open(QFile::ReadOnly);
    F2.open(QFile::WriteOnly);

    F2.write(F1.readAll());
    F1.close();
    F2.close();
    F1.remove();
}

void Denis::FileDel(QString in)
{
    QFile F1(in);
    F1.remove();
}

int Denis::ApplyChangesToFileSystem(QStringList &Root, QStringList &FileList, int out, int del)
{
    if (
            (FileList.length() == 0) ||
            (FileList.length() <= out) ||
            (FileList.length() <= del) ||
            ((out == del) && (out != -1)) ||
            (out > del) ||
            (out < -1) ||
            (del < -1)
            )
        return -1;
/*
    if (del != -1)
    {
        for(int i = del; i < FileList.length(); i++)
            del(root+FileList[i]);
    }
*/

    if ((out != 0) && (del != 0))
    {
        int n = 0;
        if ((out == -1) && (del == -1))
            n = FileList.length();
        else
            if ((out == -1) && (del =! -1))
                n = del;
            else
                n = out;

        QString path1;
        QString path2;
        for(int i = 0; i < n; i++)
        {
            path1 = Root[0]+FileList[i];
            path2 = Root[1]+FileList[i];
            FileCopy(path2,path1);
        }
    }
/*
    if (out != -1)
    {
        Report->append(lang_warnings_dialog_out);
        if (del == -1) del = FileList.length();
        for(int i = out; i < del; i++)
            Report->append("   "+FileList[i]);
    }
*/
    return 0;
}
